package com.caishi.lkx.exam.service.impl;

import com.caishi.lkx.exam.mapper.UserCountRecordsMapper;
import com.caishi.lkx.exam.model.UserCountRecordsModel;
import com.caishi.lkx.exam.service.IUserCountRecordsService;
import com.zzw.common.Wrappers;
import com.zzw.common.entity.IBSMapper;
import com.zzw.common.exception.BizRuntimeException;
import com.zzw.common.lock.RedissonLock;

import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;

@Service
public class UserCountRecordsServiceImpl implements IUserCountRecordsService {

    @Resource
    private UserCountRecordsMapper mapper;

    @Override
    public IBSMapper<UserCountRecordsModel, Long> getMapper() {
        return mapper;
    }


    public UserCountRecordsModel userTodayData(String userId) {
        var res = selectOne(wrappers()
                .eq(UserCountRecordsModel::getUserId, userId)
        );
        if (res != null && !res.getToday().equals(LocalDate.now())) {
            res.setTc(0);
        }
        return res == null ? new UserCountRecordsModel() : res;
    }

    @SneakyThrows
    @Override
    public void addPaper(String userId) {
        mapper.update(null, Wrappers.<UserCountRecordsModel>lambdaUpdate()
                .setSql(" pc = pc + 1")
                .eq(UserCountRecordsModel::getUserId, userId)
        );
    }

    @SneakyThrows
    @Override
    public void addCount(String userId, Integer ec, Integer count) {
        if (ec > count) throw new BizRuntimeException();
        if (count == 0) return;
        var today = LocalDate.now();
        if (mapper.update(null, Wrappers.<UserCountRecordsModel>lambdaUpdate()
                .setSql(String.format(" tc = tc + %d,dc = dc + %d, ec = ec + %d", count, count, ec))
                .eq(UserCountRecordsModel::getUserId, userId)
                .eq(UserCountRecordsModel::getToday, today)
        ) == 0) {
            RedissonLock.lock("UserCountRecordsService:" + userId, k -> {
                var res = selectOne(wrappers()
                        .eq(UserCountRecordsModel::getUserId, userId));
                if (res == null) {
                    insert(UserCountRecordsModel.builder()
                            .userId(userId)
                            .today(today)
                            .dc(count)
                            .tc(count)
                            .ec(ec)
                            .build());
                } else {
                    if (res.getToday().equals(today)) {
                        res.setTc(res.getTc() + count);
                    } else {
                        res.setTc(count);
                    }
                    res.setToday(today);
                    res.setDc(res.getDc() + count);
                    res.setEc(res.getEc() + ec);
                    update(res);
                }
            });
        }
    }

}
